package com.jl.card.parse.part;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import com.jl.card.parse.IAPDUComponent;
import com.jl.card.parse.INSPoll;
import com.jl.util.HexUtil;

import opencard.core.terminal.CommandAPDU;
import opencard.core.terminal.ResponseAPDU;

public class APDUComponentManager implements IAPDUComponent{
	
	private ResponseAPDU res;
	private CommandAPDU cmd;
	
	private List<IAPDUComponent> children = new ArrayList<IAPDUComponent>();
	private IAPDUComponent parent;

	public APDUComponentManager(CommandAPDU cmd,ResponseAPDU res){
		this.cmd = new CommandAPDU(cmd.getBytes(),cmd.getLength());
		this.res = new ResponseAPDU(res.getBytes());
	}
	
	/**
	 * A0A4000002-SELECT
	 * @return
	 */
	@Override
	public String getSummary(){
		StringBuilder sb = new StringBuilder();
		sb.append(INSPoll.getDescription(cmd.getByte(1))).append("-");
		sb.append(HexUtil.toHexCompact(cmd.getBytes(),0,5));
		return sb.toString();
	}
	
	@Override
	public void analyse() {
		children.clear();
		byte[] _cmd = cmd.getBytes();
		new P1P2Part(this, Arrays.copyOfRange(_cmd, 2, 4));
		if(_cmd.length > 5){
			new CDATAPart(this, Arrays.copyOfRange(_cmd, 5, (cmd.getByte(4) & 0xFF) + 5));
		}
		byte[] _res = res.data();
		if(_res != null && _res.length > 0){
			new RDATAPart(this, _res);
		}
		new SWPart(this, new byte[]{res.sw1(),res.sw2()});
	}

	@Override
	public Iterator<IAPDUComponent> getIterator() {
		analyse();
		return new Iterator<IAPDUComponent>() {
			int index = 0;
			@Override
			public boolean hasNext() {
				return index < children.size();
			}

			@Override
			public IAPDUComponent next() {
				return  children.get(index++);
			}

			@Override
			public void remove() {
			}
		};
	}

	@Override
	public IAPDUComponent getParent() {
		return parent;
	}

	@Override
	public Object[] childrenToArray() {
		analyse();
		return children.toArray(new IAPDUComponent[]{});
	}

	@Override
	public boolean hasChildren() {
		return true;
	}
	
	public byte getIns(){
		return (byte) cmd.getByte(1);
	}

	@Override
	public void add(IAPDUComponent apduPart) {
		children.add(apduPart);
	}
}
